﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using System.Windows.Media.Imaging;
using MSRoomLocator.Models;
using MSRoomLocator.ViewModels;
using System.Xml.Linq;

namespace MSRoomLocator
{
    public partial class FloorPlan : PhoneApplicationPage
    {
        private double _initialAngle;
        private double _initialScale;
        XDocument xdoc;
        XElement goalroomNode;
        List<XElement> roomNodes;

        public FloorPlan()
        {

            InitializeComponent();

            SolidColorBrush darkThemeBrush = new SolidColorBrush(Color.FromArgb(255, 0, 0, 0));
            if (App.ViewModel.Theme == "Light")
            {
                targetIconText.Foreground = darkThemeBrush;
                startIconText.Foreground = darkThemeBrush;

                foreach (var child in this.iconsPanel.Children)
                {
                    if (child is TextBlock)
                    {
                        (child as TextBlock).Foreground = darkThemeBrush;
                    }
                }
            }
        }

        #region Touch events
        private void OnPinchStarted(object sender, PinchStartedGestureEventArgs e)
        {
            // store the initial rotation angle and scaling
            _initialAngle = ImageTransformation.Rotation;
            _initialScale = ImageTransformation.ScaleX;

            // calculate the center for the zooming
            Point firstTouch = e.GetPosition(this.RootCanvas, 0);
            Point secondTouch = e.GetPosition(this.RootCanvas, 1);

            Point center = new Point(firstTouch.X + (secondTouch.X - firstTouch.X) / 2.0,
                                        firstTouch.Y + (secondTouch.Y - firstTouch.Y) / 2.0);




            ImageTransformation.CenterX = center.X;
            ImageTransformation.CenterY = center.Y;

            //this.MyLocationFlag2.SetValue(Canvas.LeftProperty, firstTouch.X);
            //this.MyLocationFlag2.SetValue(Canvas.TopProperty, firstTouch.Y);
            //this.MyLocationFlag3.SetValue(Canvas.LeftProperty, secondTouch.X);
            //this.MyLocationFlag3.SetValue(Canvas.TopProperty, secondTouch.Y);
        }

        private void OnPinchDelta(object sender, PinchGestureEventArgs e)
        {
            // update the rotation and scaling
            //ImageTransformation.Rotation = _initialAngle + e.TotalAngleDelta;
            ImageTransformation.ScaleX = _initialScale * e.DistanceRatio;
            ImageTransformation.ScaleY = ImageTransformation.ScaleX;

        }

        private void GestureListener_PinchCompleted(object sender, PinchGestureEventArgs e)
        {
            this.DrawFloorPlan();
        }

        private void GestureListener_DragStarted(object sender, DragStartedGestureEventArgs e)
        {

        }

        private void GestureListener_DragDelta(object sender, DragDeltaGestureEventArgs e)
        {
            ImageTransformation.TranslateX += e.HorizontalChange;
            ImageTransformation.TranslateY += e.VerticalChange;
        }

        private void GestureListener_DragCompleted(object sender, DragCompletedGestureEventArgs e)
        {
            this.DrawFloorPlan();
        }

        private void gobackBtn_Click(object sender, EventArgs e)
        {
            NavigationService.Navigate(new Uri("/MainPage.xaml", UriKind.Relative));
        }
        #endregion



        protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
        {
            xdoc = XDocument.Load(string.Format("Content/PlanPath/{0}F{1}.xml", App.ViewModel.SelectedBuilding.Name, App.ViewModel.GoalRoom.Floor));
            goalroomNode = (from path in xdoc.Descendants(XName.Get("path", "http://www.w3.org/2000/svg"))
                                where path.Attribute("id") != null && path.Attribute("id").Value == App.ViewModel.GoalRoom.ID
                                select path).FirstOrDefault();
            roomNodes = (from g in xdoc.Descendants(XName.Get("g", "http://www.w3.org/2000/svg"))
                        where g.Attribute("id").Value == "rooms"
                        select g).Descendants(XName.Get("path", "http://www.w3.org/2000/svg")).ToList();

            // zoom floor plan to fit
            ImageTransformation.TranslateX = 375 - double.Parse(goalroomNode.Attribute("x2").Value);
            ImageTransformation.TranslateY = 200 - double.Parse(goalroomNode.Attribute("y2").Value);
            ImageTransformation.TranslateX *= ImageTransformation.ScaleX;
            ImageTransformation.TranslateY *= ImageTransformation.ScaleY;
            ImageTransformation.CenterX = 375;
            ImageTransformation.CenterY = 200;

            this.DrawFloorPlan();
        }

        void DrawFloorPlan()
        {
            App.ViewModel.ViewPort.ApplyViewport(this.ImageTransformation);

            // draw floor plan of selected building and floor
            //this.background.Children.Clear();
            //this.DrawGroupOfPath(xdoc, "background");
            this.rooms.Children.Clear();
            this.DrawGroupOfPath();

            #region draw lables
            this.labels.Children.Clear();
            var lableGroup = from g in xdoc.Descendants(XName.Get("g", "http://www.w3.org/2000/svg"))
                             where g.Attribute("id").Value == "labels"
                             select g;
            foreach (var t in lableGroup.Descendants(XName.Get("text", "http://www.w3.org/2000/svg")))
            {
                double x = double.Parse(t.Attribute("x").Value);
                double y = double.Parse(t.Attribute("y").Value);
                if (App.ViewModel.ViewPort.IsInScreen(x, y))
                {
                    if (this.IsRoadLabel(t.Value)) continue;
                    TextBlock tb = new TextBlock();
                    tb.Text = t.Value;
                    if (tb.Text != App.ViewModel.GoalRoom.ID)
                    {
                        tb.Foreground = new SolidColorBrush(Color.FromArgb(255, 255, 255, 255));
                    }
                    else
                    {
                        tb.Foreground = new SolidColorBrush(Color.FromArgb(255, 0, 0, 0));
                    }
                    tb.FontSize = 8;
                    if (t.Attribute("transform") != null && t.Attribute("transform").Value.IndexOf("rotate") != -1)
                    {
                        CompositeTransform ct = new CompositeTransform();
                        string attribute = t.Attribute("transform").Value;
                        int i = attribute.IndexOf("rotate");
                        int j = attribute.IndexOf(" ", i);
                        string rotate = attribute.Substring(i, j - i + 1);
                        ct.Rotation = int.Parse(rotate.Replace("rotate(", string.Empty).Replace(")", string.Empty));
                        tb.RenderTransform = ct;
                    }

                    tb.SetValue(Canvas.LeftProperty, x - 10);
                    tb.SetValue(Canvas.TopProperty, y - 6);
                    this.labels.Children.Add(tb);
                }
            }
            #endregion

            // draw goal room lable
            string goalroomPathXaml = string.Format("<Path xmlns=\"http://schemas.microsoft.com/client/2007\" Data=\"{0}\" Fill=\"Transparent\" StrokeThickness=\"4\" Stroke=\"Red\"></Path>",
                            goalroomNode.Attribute("d").Value);
            this.rooms.Children.Add((Path)System.Windows.Markup.XamlReader.Load(goalroomPathXaml));

            #region show view port for debug
            //Canvas viewport = new Canvas();
            //viewport.SetValue(Canvas.LeftProperty, App.ViewModel.ViewPort.ScreenX);
            //viewport.SetValue(Canvas.TopProperty, App.ViewModel.ViewPort.ScreenY);
            //viewport.Width = App.ViewModel.ViewPort.ScreenWidth;
            //viewport.Height = App.ViewModel.ViewPort.ScreenHeight;
            //viewport.Background = new SolidColorBrush(Color.FromArgb(100, 0, 255, 0));
            //`this.background.Children.Add(viewport);
            #endregion
        }

        void DrawRoomLable(string roomName)
        {
            var textEle = (from g in xdoc.Descendants(XName.Get("text", "http://www.w3.org/2000/svg"))
                           where g.Value == roomName
                           select g).FirstOrDefault();

            double x = double.Parse(textEle.Attribute("x").Value);
            double y = double.Parse(textEle.Attribute("y").Value);
            if (App.ViewModel.ViewPort.IsInScreen(x, y))
            {
                TextBlock tb = new TextBlock();
                tb.Text = roomName;
                tb.FontSize = 10;
                if (textEle.Attribute("transform") != null && textEle.Attribute("transform").Value.IndexOf("rotate") != -1)
                {
                    CompositeTransform ct = new CompositeTransform();
                    string attribute = textEle.Attribute("transform").Value;
                    int i = attribute.IndexOf("rotate");
                    int j = attribute.IndexOf(" ", i);
                    string rotate = attribute.Substring(i, j - i + 1);
                    ct.Rotation = int.Parse(rotate.Replace("rotate(", string.Empty).Replace(")", string.Empty));
                    tb.RenderTransform = ct;
                }

                tb.SetValue(Canvas.LeftProperty, x - 10);
                tb.SetValue(Canvas.TopProperty, y - 6);
                this.labels.Children.Add(tb);
            }
        }

        void DrawGroupOfPath()
        {
            foreach (var p in roomNodes)
            {
                string data = p.Attribute("d").Value;
                string fillColor = "#333333";

                switch (p.Attribute("desc").Value)
                {
                    case "Conference":
                        fillColor = "YellowGreen";
                        break;
                    case "Open Meeting":
                        fillColor = "Coral";
                        break;
                    default: break;
                }

                if (p.Attribute("desc").Value.Contains("Printer"))
                {
                    fillColor = "LightBlue";
                }
                if (p.Attribute("desc").Value.Contains("Cafe"))
                {
                    fillColor = "Brown";
                }
                string pathXaml = string.Format("<Path xmlns=\"http://schemas.microsoft.com/client/2007\" Data=\"{0}\" StrokeThickness=\"1\" Stroke=\"White\" Fill=\"{1}\"></Path>", data, fillColor);
                this.rooms.Children.Add((Path)System.Windows.Markup.XamlReader.Load(pathXaml));
            }
        }

        bool IsRoadLabel(string name)
        {
            foreach (var room in this.roomNodes.Where(r => r.Attribute("desc").Value == "Circulation (Secondary)"))
            {
                string id = room.Attribute("id").Value;
                if (string.Compare(id, name, StringComparison.OrdinalIgnoreCase) == 0) return true;
            }

            return false;
        }

        private void UpdateButton_Click(object sender, RoutedEventArgs e)
        {
            App.ViewModel.StartRoom = App.ViewModel.GetRoom(SelectRoomTextBox.Text);
            if (App.ViewModel.StartRoom != null)
            {
                #region draw start room
                this.startingrooms.Children.Clear();
                var startroomNode = from path in xdoc.Descendants(XName.Get("path", "http://www.w3.org/2000/svg"))
                                    where path.Attribute("id") != null && path.Attribute("id").Value == App.ViewModel.StartRoom.ID
                                    select path;
                string startroomPathXaml = string.Format("<Path xmlns=\"http://schemas.microsoft.com/client/2007\" Data=\"{0}\" Fill=\"Transparent\" StrokeThickness=\"4\" Stroke=\"Yellow\"></Path>",
                                startroomNode.FirstOrDefault().Attribute("d").Value);
                this.startingrooms.Children.Add((Path)System.Windows.Markup.XamlReader.Load(startroomPathXaml));
                #endregion
            }
            else
            {
                // show room not found
                this.SelectRoomTextBox.Text = "Sorry, no room found.";
            }
        }

        private void SelectRoomTextBox_Tap(object sender, System.Windows.Input.GestureEventArgs e)
        {
            SelectRoomTextBox.Text = "";
        }
    }
}
